package com.shrct.businessprocess.project.impl;

import com.google.common.base.Objects;
import com.shrct.businessprocess.project.RCCommissionYearConfig;
import com.shrct.businessprocess.project.RCSalesAssignment;
import com.shrct.businessprocess.project.RCSalesCommissionOverflowConfigItem;
import com.shrct.businessprocess.project.RCSalesCommissionYearConfig;
import com.shrct.businessprocess.project.RCSalesCommissionYearSettlement;
import com.shrct.businessprocess.project.RCSalesTeam;
import com.shrct.businessprocess.project.impl.RCCommissionYearConfigImpl;
import com.shrct.businessprocess.project.impl.RCSalesAssignmentImpl;
import com.shrct.businessprocess.project.impl.RCSalesCommissionOverflowConfigItemImpl;
import com.shrct.businessprocess.project.impl.RCSalesCommissionYearSettlementImpl;
import com.shrct.businessprocess.project.impl.RCSalesTeamImpl;
import com.shrct.businessprocess.project.proxy.RCSalesCommissionYearConfigProxy;
import com.uniquesoft.uidl.validation.Validates;
import edu.fudan.mylang.common.NumberExtensions;
import edu.fudan.mylang.pf.BaseModelObject;
import edu.fudan.mylang.pf.IGenericQuery;
import edu.fudan.mylang.pf.IObjectFactory;
import edu.fudan.mylang.utils.DateUtil;
import java.util.Collection;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.eclipse.xtext.xbase.lib.DoubleExtensions;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.hibernate.annotations.DiscriminatorOptions;

@Entity
@DiscriminatorValue("RCSALESCOMMISSIONYEARCONFIG_TYPE")
@DiscriminatorOptions(force = true)
@DiscriminatorColumn(length = 64)
@Table(name = "rcsalescommissionyearconfig")
public class RCSalesCommissionYearConfigImpl extends BaseModelObject implements RCSalesCommissionYearConfig {
  public RCSalesCommissionYearConfigImpl() {
    super();
  }
  
  public RCSalesCommissionYearConfigImpl(final RCCommissionYearConfig overallConfig) {
    super();
    this.overallConfig = overallConfig;
  }
  
  @JoinColumn(name = "overallConfig_id")
  @ManyToOne(targetEntity = RCCommissionYearConfigImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCCommissionYearConfig overallConfig;
  
  public RCCommissionYearConfig getOverallConfig() {
    return this.overallConfig;
  }
  
  public RCSalesCommissionYearConfig setOverallConfig(final RCCommissionYearConfig overallConfig) {
    this.overallConfig = overallConfig;
    return this;			
    
  }
  
  @JoinColumn(name = "saler_id")
  @ManyToOne(targetEntity = RCSalesAssignmentImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCSalesAssignment saler;
  
  public RCSalesAssignment getSaler() {
    return this.saler;
  }
  
  public RCSalesCommissionYearConfig setSaler(final RCSalesAssignment saler) {
    this.saler = saler;
    return this;			
    
  }
  
  private Double rate = Double.valueOf(0d);
  
  public Double getRate() {
    return this.rate;
  }
  
  public RCSalesCommissionYearConfig setRate(final Double rate) {
    this.rate = rate;
    return this;			
    
  }
  
  private Date startDate;
  
  public Date getStartDate() {
    return this.startDate;
  }
  
  public RCSalesCommissionYearConfig setStartDate(final Date startDate) {
    this.startDate = startDate;
    return this;			
    
  }
  
  private Double baseGrossProfitGoalFactor = Double.valueOf(8d);
  
  public Double getBaseGrossProfitGoalFactor() {
    return this.baseGrossProfitGoalFactor;
  }
  
  public RCSalesCommissionYearConfig setBaseGrossProfitGoalFactor(final Double baseGrossProfitGoalFactor) {
    this.baseGrossProfitGoalFactor = baseGrossProfitGoalFactor;
    return this;			
    
  }
  
  private Double baseGrossProfitGoal = Double.valueOf(0d);
  
  public Double getBaseGrossProfitGoal() {
    return this.baseGrossProfitGoal;
  }
  
  public RCSalesCommissionYearConfig setBaseGrossProfitGoal(final Double baseGrossProfitGoal) {
    this.baseGrossProfitGoal = baseGrossProfitGoal;
    return this;			
    
  }
  
  private Double monthlySalary = Double.valueOf(0d);
  
  public Double getMonthlySalary() {
    return this.monthlySalary;
  }
  
  public RCSalesCommissionYearConfig setMonthlySalary(final Double monthlySalary) {
    this.monthlySalary = monthlySalary;
    return this;			
    
  }
  
  private Double additionalSharedCost = Double.valueOf(0d);
  
  public Double getAdditionalSharedCost() {
    return this.additionalSharedCost;
  }
  
  public RCSalesCommissionYearConfig setAdditionalSharedCost(final Double additionalSharedCost) {
    this.additionalSharedCost = additionalSharedCost;
    return this;			
    
  }
  
  private Double yearAmountTarget = Double.valueOf(0d);
  
  public Double getYearAmountTarget() {
    return this.yearAmountTarget;
  }
  
  public RCSalesCommissionYearConfig setYearAmountTarget(final Double yearAmountTarget) {
    this.yearAmountTarget = yearAmountTarget;
    return this;			
    
  }
  
  private Double costTarget = Double.valueOf(0d);
  
  public Double getCostTarget() {
    return this.costTarget;
  }
  
  public RCSalesCommissionYearConfig setCostTarget(final Double costTarget) {
    this.costTarget = costTarget;
    return this;			
    
  }
  
  private Double sharedCostTarget = Double.valueOf(0d);
  
  public Double getSharedCostTarget() {
    return this.sharedCostTarget;
  }
  
  public RCSalesCommissionYearConfig setSharedCostTarget(final Double sharedCostTarget) {
    this.sharedCostTarget = sharedCostTarget;
    return this;			
    
  }
  
  public Integer getOnJobMonthsTarget() {
    int _xblockexpression = (int) 0;
    {
      Date _xifexpression = null;
      Date _leaveDate = this.saler.getLeaveDate();
      boolean _equals = Objects.equal(_leaveDate, null);
      if (_equals) {
        Date _lastDayOfYear = DateUtil.lastDayOfYear(this.startDate);
        _xifexpression = _lastDayOfYear;
      } else {
        Date _lastDayOfYear_1 = DateUtil.lastDayOfYear(this.startDate);
        Date _leaveDate_1 = this.saler.getLeaveDate();
        Date _min = DateUtil.min(_lastDayOfYear_1, _leaveDate_1);
        Date _max = DateUtil.max(_min, this.startDate);
        _xifexpression = _max;
      }
      final Date lastDay = _xifexpression;
      Double _betweenMonth = DateUtil.betweenMonth(this.startDate, lastDay);
      long _round = Math.round((_betweenMonth).doubleValue());
      int _intValue = Long.valueOf(_round).intValue();
      _xblockexpression = (_intValue);
    }
    return Integer.valueOf(_xblockexpression);
  }
  
  @JoinColumn(name = "lastSettlement_id")
  @ManyToOne(targetEntity = RCSalesCommissionYearSettlementImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCSalesCommissionYearSettlement lastSettlement;
  
  public RCSalesCommissionYearSettlement getLastSettlement() {
    return this.lastSettlement;
  }
  
  public RCSalesCommissionYearConfig setLastSettlement(final RCSalesCommissionYearSettlement lastSettlement) {
    this.lastSettlement = lastSettlement;
    return this;			
    
  }
  
  public RCSalesCommissionYearSettlement getSettlement() {
    IGenericQuery<RCSalesCommissionYearSettlement> query=getObjectFactory().createGenericQuery(RCSalesCommissionYearSettlement.class,"select e from com.shrct.businessprocess.project.impl.RCSalesCommissionYearSettlementImpl as e   where ((e.yearConfig) = (:this)) and  e.active = 1      ").setParameter("this",this);
    RCSalesCommissionYearSettlement _uniqueResult = query.uniqueResult();
    return _uniqueResult;
  }
  
  public void update(final Procedure1<? super RCSalesCommissionYearConfig> updater) {
    updater.apply(this);
    this.checkValid();
  }
  
  @OneToMany(targetEntity = RCSalesCommissionOverflowConfigItemImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, mappedBy = "config")
  private Collection<RCSalesCommissionOverflowConfigItem> overflowConfigItems = new java.util.ArrayList<com.shrct.businessprocess.project.RCSalesCommissionOverflowConfigItem>();;
  
  public Collection<RCSalesCommissionOverflowConfigItem> getOverflowConfigItems() {
    return this.overflowConfigItems;
  }
  
  public RCSalesCommissionOverflowConfigItem createAndAddtoOverflowConfigItems() {
    getOverflowConfigItems().size();
    com.shrct.businessprocess.project.RCSalesCommissionOverflowConfigItem rCSalesCommissionOverflowConfigItem = new com.shrct.businessprocess.project.impl.RCSalesCommissionOverflowConfigItemImpl(this);
    getObjectFactory().create(rCSalesCommissionOverflowConfigItem);
    getOverflowConfigItems().add(rCSalesCommissionOverflowConfigItem);
    return rCSalesCommissionOverflowConfigItem;
    
  }
  
  public RCSalesCommissionOverflowConfigItem createAndAddtoOverflowConfigItems(final Procedure1<RCSalesCommissionOverflowConfigItem> updater) {
    getOverflowConfigItems().size();
    com.shrct.businessprocess.project.RCSalesCommissionOverflowConfigItem rCSalesCommissionOverflowConfigItem = new com.shrct.businessprocess.project.impl.RCSalesCommissionOverflowConfigItemImpl(this);
    getObjectFactory().create(rCSalesCommissionOverflowConfigItem);
    getOverflowConfigItems().add(rCSalesCommissionOverflowConfigItem);
    return rCSalesCommissionOverflowConfigItem;
    
  }
  
  public RCSalesCommissionYearConfig removeAllOverflowConfigItems() {
    for(RCSalesCommissionOverflowConfigItem obj : this.overflowConfigItems){
    	getObjectFactory().delete(obj);
    }
    this.overflowConfigItems.clear();
    return this;	
    
  }
  
  public RCSalesCommissionYearConfig removeFromOverflowConfigItems(final RCSalesCommissionOverflowConfigItem rCSalesCommissionOverflowConfigItem) {
    this.overflowConfigItems.remove(rCSalesCommissionOverflowConfigItem);
    getObjectFactory().delete(rCSalesCommissionOverflowConfigItem);
    return this;
    
  }
  
  public RCSalesCommissionOverflowConfigItem createConfigItem(final Procedure1<? super RCSalesCommissionOverflowConfigItem> init) {
    RCSalesCommissionOverflowConfigItem _createAndAddtoOverflowConfigItems = this.createAndAddtoOverflowConfigItems();
    final Procedure1<RCSalesCommissionOverflowConfigItem> _function = new Procedure1<RCSalesCommissionOverflowConfigItem>() {
        public void apply(final RCSalesCommissionOverflowConfigItem it) {
          init.apply(it);
          it.checkValid();
        }
      };
    RCSalesCommissionOverflowConfigItem _doubleArrow = ObjectExtensions.<RCSalesCommissionOverflowConfigItem>operator_doubleArrow(_createAndAddtoOverflowConfigItems, _function);
    return _doubleArrow;
  }
  
  public void deleteConfigItem(final RCSalesCommissionOverflowConfigItem item) {
    this.removeFromOverflowConfigItems(item);
  }
  
  @OneToMany(targetEntity = RCSalesTeamImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, mappedBy = "config")
  private Collection<RCSalesTeam> teams = new java.util.ArrayList<com.shrct.businessprocess.project.RCSalesTeam>();;
  
  public Collection<RCSalesTeam> getTeams() {
    return this.teams;
  }
  
  public RCSalesTeam createAndAddtoTeams() {
    getTeams().size();
    com.shrct.businessprocess.project.RCSalesTeam rCSalesTeam = new com.shrct.businessprocess.project.impl.RCSalesTeamImpl(this);
    getObjectFactory().create(rCSalesTeam);
    getTeams().add(rCSalesTeam);
    return rCSalesTeam;
    
  }
  
  public RCSalesTeam createAndAddtoTeams(final Procedure1<RCSalesTeam> updater) {
    getTeams().size();
    com.shrct.businessprocess.project.RCSalesTeam rCSalesTeam = new com.shrct.businessprocess.project.impl.RCSalesTeamImpl(this);
    getObjectFactory().create(rCSalesTeam);
    getTeams().add(rCSalesTeam);
    return rCSalesTeam;
    
  }
  
  public RCSalesCommissionYearConfig removeAllTeams() {
    for(RCSalesTeam obj : this.teams){
    	getObjectFactory().delete(obj);
    }
    this.teams.clear();
    return this;	
    
  }
  
  public RCSalesCommissionYearConfig removeFromTeams(final RCSalesTeam rCSalesTeam) {
    this.teams.remove(rCSalesTeam);
    getObjectFactory().delete(rCSalesTeam);
    return this;
    
  }
  
  public RCSalesTeam createTeam(final Procedure1<? super RCSalesTeam> init) {
    RCSalesTeam _createAndAddtoTeams = this.createAndAddtoTeams();
    final Procedure1<RCSalesTeam> _function = new Procedure1<RCSalesTeam>() {
        public void apply(final RCSalesTeam it) {
          init.apply(it);
          it.checkValid();
        }
      };
    RCSalesTeam _doubleArrow = ObjectExtensions.<RCSalesTeam>operator_doubleArrow(_createAndAddtoTeams, _function);
    return _doubleArrow;
  }
  
  public void deleteTeam(final RCSalesTeam item) {
    this.removeFromTeams(item);
  }
  
  public Double getTotalCommissionAmountPaid() {
    IGenericQuery<Double> query=getObjectFactory().createGenericQuery(Double.class,"select sum(e.commissionAmount) from com.shrct.businessprocess.project.impl.RCSaleCommissionPayment4CalcSettlementYearImpl as e   where ((e.contract) = (:this)) and  e.active = 1      ").setParameter("this",this);
    Double _uniqueResult = query.uniqueResult();
    Double _nullsafe = NumberExtensions.nullsafe(_uniqueResult);
    return _nullsafe;
  }
  
  public Double getTotalCommission() {
    RCSalesCommissionYearSettlement _settlement = this.getSettlement();
    Double _commissionAmount = _settlement==null?(Double)null:_settlement.getCommissionAmount();
    Double _nullsafe = NumberExtensions.nullsafe(_commissionAmount);
    return _nullsafe;
  }
  
  public Double getTotalOverflowCommissionAmountPaid() {
    IGenericQuery<Double> query=getObjectFactory().createGenericQuery(Double.class,"select sum(e.overflowCommissionAmount) from com.shrct.businessprocess.project.impl.RCSaleCommissionPayment4CalcSettlementYearImpl as e   where ((e.contract) = (:this)) and  e.active = 1      ").setParameter("this",this);
    Double _uniqueResult = query.uniqueResult();
    Double _nullsafe = NumberExtensions.nullsafe(_uniqueResult);
    return _nullsafe;
  }
  
  public Double getTotalOverflowCommissionAmount() {
    RCSalesCommissionYearSettlement _settlement = this.getSettlement();
    Double _overflowCommissionAmount = _settlement==null?(Double)null:_settlement.getOverflowCommissionAmount();
    Double _nullsafe = NumberExtensions.nullsafe(_overflowCommissionAmount);
    return _nullsafe;
  }
  
  public Double getTotalTeamPrizeAmountPaid() {
    IGenericQuery<Double> query=getObjectFactory().createGenericQuery(Double.class,"select sum(e.teamPrizeAmount) from com.shrct.businessprocess.project.impl.RCSaleCommissionPayment4CalcSettlementYearImpl as e   where ((e.contract) = (:this)) and  e.active = 1      ").setParameter("this",this);
    Double _uniqueResult = query.uniqueResult();
    Double _nullsafe = NumberExtensions.nullsafe(_uniqueResult);
    return _nullsafe;
  }
  
  public Double getTotalTeamPrizeAmount() {
    RCSalesCommissionYearSettlement _settlement = this.getSettlement();
    Double _teamPrizeAmount = _settlement==null?(Double)null:_settlement.getTeamPrizeAmount();
    Double _nullsafe = NumberExtensions.nullsafe(_teamPrizeAmount);
    return _nullsafe;
  }
  
  public Double getTotalAmount() {
    Double _totalCommission = this.getTotalCommission();
    Double _totalOverflowCommissionAmount = this.getTotalOverflowCommissionAmount();
    double _plus = DoubleExtensions.operator_plus(_totalCommission, _totalOverflowCommissionAmount);
    Double _totalTeamPrizeAmount = this.getTotalTeamPrizeAmount();
    double _plus_1 = (_plus + (_totalTeamPrizeAmount).doubleValue());
    return Double.valueOf(_plus_1);
  }
  
  public Double getTotalAmountPaid() {
    Double _totalCommissionAmountPaid = this.getTotalCommissionAmountPaid();
    Double _totalOverflowCommissionAmountPaid = this.getTotalOverflowCommissionAmountPaid();
    double _plus = DoubleExtensions.operator_plus(_totalCommissionAmountPaid, _totalOverflowCommissionAmountPaid);
    Double _totalTeamPrizeAmountPaid = this.getTotalTeamPrizeAmountPaid();
    double _plus_1 = (_plus + (_totalTeamPrizeAmountPaid).doubleValue());
    return Double.valueOf(_plus_1);
  }
  
  public void checkValid() {
    boolean _notEquals = (!Objects.equal(this.saler, null));
    Validates.Assert(_notEquals, "\u9500\u552E\u5FC5\u987B\u8BBE\u7F6E");
    Collection<RCSalesCommissionYearConfig> _items = this.overallConfig.getItems();
    final Function1<RCSalesCommissionYearConfig,Boolean> _function = new Function1<RCSalesCommissionYearConfig,Boolean>() {
        public Boolean apply(final RCSalesCommissionYearConfig it) {
          RCSalesAssignment _saler = it.getSaler();
          boolean _equals = Objects.equal(_saler, RCSalesCommissionYearConfigImpl.this.saler);
          return Boolean.valueOf(_equals);
        }
      };
    Iterable<RCSalesCommissionYearConfig> _filter = IterableExtensions.<RCSalesCommissionYearConfig>filter(_items, _function);
    int _size = IterableExtensions.size(_filter);
    boolean _equals = (_size == 1);
    Validates.Assert(_equals, "\u6BCF\u4E2A\u9500\u552E\u53EA\u80FD\u6709\u4E00\u4E2A\u6307\u6807");
    boolean _notEquals_1 = (!Objects.equal(this.rate, null));
    Validates.Assert(_notEquals_1, "\u4F63\u91D1\u7387\u5FC5\u987B\u8BBE\u7F6E");
    boolean _notEquals_2 = (!Objects.equal(this.startDate, null));
    Validates.Assert(_notEquals_2, "\u8D77\u59CB\u65E5\u671F\u5FC5\u987B\u8BBE\u7F6E");
    boolean _notEquals_3 = (!Objects.equal(this.baseGrossProfitGoal, null));
    Validates.Assert(_notEquals_3, "\u9884\u8BA1\u4FDD\u5E95\u6BDB\u5229 \u5FC5\u987B\u8BBE\u7F6E");
    boolean _notEquals_4 = (!Objects.equal(this.baseGrossProfitGoalFactor, null));
    Validates.Assert(_notEquals_4, "\u4FDD\u5E95\u6BDB\u5229\u56E0\u5B50\u5FC5\u987B\u8BBE\u7F6E");
    boolean _notEquals_5 = (!Objects.equal(this.monthlySalary, null));
    Validates.Assert(_notEquals_5, "\u672C\u5E74\u5EA6\u6708\u5DE5\u8D44\u5FC5\u987B\u8BBE\u7F6E");
    boolean _notEquals_6 = (!Objects.equal(this.additionalSharedCost, null));
    Validates.Assert(_notEquals_6, "\u5B9E\u9645\u8D39\u7528\u5FC5\u987B\u8BBE\u7F6E");
  }
  
  public static RCSalesCommissionYearConfig create(final RCCommissionYearConfig overallConfig, final IObjectFactory objectFactory) {
    com.shrct.businessprocess.project.RCSalesCommissionYearConfig rCSalesCommissionYearConfig = new com.shrct.businessprocess.project.impl.RCSalesCommissionYearConfigImpl(
    	overallConfig
    );
    objectFactory.create(rCSalesCommissionYearConfig);
    return rCSalesCommissionYearConfig;			
    
  }
  
  public static RCSalesCommissionYearConfig createRCSalesCommissionYearConfigImpl(final RCCommissionYearConfig overallConfig, final IObjectFactory objectFactory, final Procedure1<RCSalesCommissionYearConfig> init) {
    com.shrct.businessprocess.project.RCSalesCommissionYearConfig rCSalesCommissionYearConfig = new com.shrct.businessprocess.project.impl.RCSalesCommissionYearConfigImpl(
    	overallConfig
    );
    objectFactory.create(rCSalesCommissionYearConfig);
    init.apply(rCSalesCommissionYearConfig);
    
    return rCSalesCommissionYearConfig;			
    
  }
  
  public RCSalesCommissionYearConfigProxy toProxy() {
    com.shrct.businessprocess.project.proxy.RCSalesCommissionYearConfigProxy proxy = new com.shrct.businessprocess.project.proxy.RCSalesCommissionYearConfigProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    return proxy;
    
  }
}
